package com.doctorpda.cdn;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.doctorpda.compresser.JsCssCompressor;

/**
 * CDN服务器路径修改 http://mcdn.doctorpda.cn/ 增加版本信息 雅虎压缩混淆
 * java -jar cdnjscss.jar D:/cdnyui/camel_yx/src/main/webapp
 * java -jar cdnjscss.jar D:/cdnyui/camel_yx/src/main/webapp cdn
 * java -jar cdnjscss.jar D:/cdnyui/camel_yx/src/main/webapp comp
 * java -jar cdnjscss.jar D:/cdnyui/camel_yx/src/main/webapp cdn-comp mcdn.doctorpda.cn
 * java -jar cdnjscss.jar D:/cdnyui/camel_yx/src/main/webapp cdn-comp 
 * @author ligx
 *
 */
public class CamelCdn {

	// http://mcdn.doctorpda.cn
	public static String	CDN_DOMAIN	= "";
	public static String	CDN			= ".cdn.";
	// 版本号
	public static long		VERSION		= 0L;
	
	// 标志位
	private static Boolean CDN_FLAG = false;
	private static Boolean COMP_FLAG = false;

	/**
	 * 需要更新的文件路径
	 * 
	 * @param args
	 *            需要更新的文件路径
	 */
	public static void main(String[] args) {
		CamelCdn cc = new CamelCdn();
		cc.getVersion();
/*		cc.checkFile(new File("d:/api"));*/
		// 需要更新的文件路径
		String sourceDir = null;

		if (args.length > 0) {
			sourceDir = args[0];
			File sourceFile = null;
			if (sourceDir != null && sourceDir.trim().length() > 0) {
				sourceFile = new File(sourceDir);
			}
			if(args.length > 1){
				String flag = args[1];
				if(flag.toLowerCase().contains("cdn")){
					CDN_FLAG = true;
				}
				if(flag.toLowerCase().contains("comp")){
					COMP_FLAG = true;
				}
			}
			if(args.length > 2){
				String domain = args[2];
				domain = domain.toLowerCase();
				if(domain.startsWith("http://")){
					CDN_DOMAIN = domain;
				}else{
					CDN_DOMAIN = "http://" + domain;
				}
			}
			// 遍历修改
			cc.checkFile(sourceFile);
			System.out.println("...............执行完毕...............");
		} else {
			System.out.println("请输入处理路径...");
		}
	}

	/**
	 * 获取版本
	 * 
	 * @return
	 */
	public long getVersion() {
		Date now = new Date();
		// 发布的版本号
		VERSION = now.getTime();
		return VERSION;
	}

	/**
	 * 对sourceDir路径下的htm模板文件进行递归遍历，更新CDN服务器后，放到targetDir目录中
	 * 
	 * @param sourceDir
	 * @param targetDir
	 * @throws IOException
	 */
	public void go(File file) throws IOException {
		if (!file.exists() || file.isDirectory())
			throw new FileNotFoundException();
		// content.htm
		String fileName = file.getName();
		// D:\api\activity\content.htm
		// String filePath = file.getAbsolutePath();

		Reader in = new FileReader(file);

		int index = fileName.lastIndexOf(".");
		String newFileName = fileName;
		if (index > 0) {
			String preFileName = fileName.substring(0, index);
			String extFileName = fileName.substring(index + 1);
			newFileName = preFileName + CamelCdn.CDN + extFileName;
		}

		File tempFile = new File(file.getParent() + "/" + newFileName);
		Writer out = new FileWriter(tempFile);

		// 读取文件，替换路径
		BufferedReader br = new BufferedReader(new FileReader(file));
		String temp = null;
		StringBuffer sb = new StringBuffer();
		temp = br.readLine();
		while (temp != null) {
			temp = temp.trim();
			// 删除空行
			if (temp.length() < 1) {
				temp = br.readLine();
				continue;
			}
			// 删除注释
			if (temp.startsWith("//")) {
				temp = br.readLine();
				continue;
			}

			sb.append(temp + "\r\n");
			temp = br.readLine();
		}
		br.close();

		String content = sb.toString();
		// 使用正则表达式匹配
		replaceCDN(out, content);

		out.close();
		in.close();
		// 删除源文件
		file.delete();
		// 把更新后的临时文件重命名为源文件
		tempFile.renameTo(file);
		// File distFile = new File(file);
		// 删除临时文件
		tempFile.delete();
		System.out.print("更新CDN域名和版本。");
		System.out.println();
	}

	/**
	 * 内容替换
	 * 
	 * @param out
	 * @param content
	 * @throws IOException
	 */
	public void replaceCDN(Writer out, String content) throws IOException {
		Pattern patternForScript = Pattern
				.compile("<script(.*?)src(\\s*=\\s*)(\"|\')(.*?)(\"|\')(.*?)>");
		Matcher matcher = patternForScript.matcher(content);
		int count = 0;
		while (matcher.find()) {
			// 找到匹配的script标签中的src属性的内容
			String _srcInScript = matcher.group(4);
			_srcInScript = _srcInScript.trim();
			if (_srcInScript.length() < 1 || _srcInScript.contains("http://"))
				continue;

			StringBuffer srcInScript = new StringBuffer();
			// CDN 服务器域名  非绝对路径，不做处理
			if (_srcInScript.startsWith("/") || _srcInScript.startsWith("${")) {
				srcInScript.append(CDN_DOMAIN).append(_srcInScript);
				// 增加版本号 使用时间戳
				if (_srcInScript.contains("?")) {
					srcInScript.append("&v=").append(VERSION);
				} else {
					srcInScript.append("?v=").append(VERSION);
				}
				content = content.replace(_srcInScript, srcInScript.toString());
				count ++;
			}
		}
		System.out.print("修改<script/>标签" + count + "处");

		Pattern patternForLink = Pattern
				.compile("<link(.*?)href(\\s*=\\s*)(\"|\')(.*?)(\"|\')(.*?)>");
		Matcher matcher2 = patternForLink.matcher(content);
		count = 0;
		while (matcher2.find()) {
			// 找到匹配的link标签中的href属性的内容
			String _hrefInLink = matcher2.group(4);
			_hrefInLink = _hrefInLink.trim();
			if (_hrefInLink.length() < 1 || _hrefInLink.contains("http://"))
				continue;

			StringBuffer hrefInLink = new StringBuffer();
			// CDN 服务器域名   非绝对路径，不做处理
			if (_hrefInLink.startsWith("/") || _hrefInLink.startsWith("${")) {
				hrefInLink.append(CDN_DOMAIN).append(_hrefInLink);
				// 增加版本号 使用时间戳
				if (_hrefInLink.contains("?")) {
					hrefInLink.append("&v=").append(VERSION);
				} else {
					hrefInLink.append("?v=").append(VERSION);
				}
				content = content.replace(_hrefInLink, hrefInLink.toString());
				count ++;
			}
		}
		System.out.print("修改<link/>标签" + count + "处");

		out.write(content.toCharArray());
	}

	/**
	 * 递归更新CDN域名
	 * 
	 * @param file
	 * @throws Exception
	 */
	public void checkFile(File file) {
		if (file.isFile()
				&& (file.getName().endsWith(".htm") || file.getName().endsWith(".html") || file.getName().endsWith(".jsp")) && CDN_FLAG) {
			System.out.print(file.getAbsolutePath() + "\t");
			try {
				go(file);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return;
		}

		if (file.isFile()
				&& (file.getName().endsWith(".js") || file.getName().endsWith(
						".css")) && COMP_FLAG) {
			if (file.getName().contains(".min"))
				return;

			System.out.print(file.getAbsolutePath() + "\t ");
			JsCssCompressor c = new JsCssCompressor();

			try {
				c.compressor(file);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return;
		}

		if (file.isDirectory()) {
			File[] files = file.listFiles();
			for (File f : files) {
				checkFile(f);
			}
		}

	}
}